Ext.namespace('RestHandler');

RestHandler.Connection = function(config){
    Ext.apply(this, config);
    this.addEvents(
        "requestsuccessful"
    );
    RestHandler.Connection.superclass.constructor.call(this);
};

Ext.extend(RestHandler.Connection, Ext.data.Connection, {
    verb: function(config){
        headers={};
        if(config.resourceXml)
            headers={'content-type' : 'text/xml'};

	    this.request({
	        url : config.url,
	        callback: function(options, success, response){
                e={
                    response: response,
                    options: options
                };

                if (config.expected_status.indexOf(response.status)>=0){
                    this.fireEvent("requestsuccessful", e)

                    if(config.success)
                        config.success(e);
	            }

	            if(config.failure)
	                config.failure(e);
	        },
	        headers : headers,
	        method : config.method,
	        xmlData : config.resourceXml,
            scope: this
	    });
    },

    create: function(url, resourceXml, config){
        var config=config || {};
        config.url=url;
        config.method="post";
        config.resourceXml=resourceXml;
        config.expected_status=[201];
        this.verb(config);
    },

    read: function(url, config){
        var config=config || {};
        config.url=url;
        config.method="get";
        config.expected_status=[200];
        this.verb(config);
    },

    update: function(url, resourceXml, config){
        var config=config || {};
        config.url=url;
        config.method="put";
        config.resourceXml=resourceXml;
        config.expected_status=[204];
        this.verb(config);
    },

    deleteResource: function(url, config){
        var config=config || {};
        config.url=url;
        config.method="delete";
        config.expected_status=[204];
        this.verb(config);
    }
});

/* Overrides para que todo funcione con ExtJS */

Ext.override(Ext.form.Action.Submit, {
    run : function(){
        var o = this.options;
        var method = this.getMethod();
        var isGet = method == 'GET';
        if(o.clientValidation === false || this.form.isValid()){
            Ext.Ajax.request(Ext.apply(this.createCallback(o), {
                form:this.form.el.dom,
                url:this.getUrl(isGet),
                method: method,
                params:!isGet ? this.getParams() : null,
                isUpload: this.form.fileUpload
            }));
        }else if (o.clientValidation !== false){ // client validation failed
            this.failureType = Ext.form.Action.CLIENT_INVALID;
            this.form.afterAction(this, false);
        }
    }
});

Ext.lib.Ajax.request = function(method, uri, cb, data, options) {
    if(options){
        var hs = options.headers;
        if(hs){
            for(var h in hs){
                if(hs.hasOwnProperty(h)){
                    this.initHeader(h, hs[h], false);
                }
            }
        }
        if(options.xmlData){
            if (!hs || !hs['Content-Type']){
                this.initHeader('Content-Type', 'text/xml', false);
            }
            method = (method ? method : (options.method ? options.method : 'POST'));
            data = options.xmlData;
        }else if(options.jsonData){
            if (!hs || !hs['Content-Type']){
                this.initHeader('Content-Type', 'application/json', false);
            }
            method = (method ? method : (options.method ? options.method : 'POST'));
            data = typeof options.jsonData == 'object' ? Ext.encode(options.jsonData) : options.jsonData;
        }
    }

    return this.asyncRequest(method, uri, cb, data);
};

Ext.lib.Ajax.asyncRequest = function(method, uri, callback, postData) {
    var o = this.getConnectionObject();

    if (!o) {
        return null;
    }
    else {
        o.conn.open(method, uri, true);

        if (this.useDefaultXhrHeader) {
            if (!this.defaultHeaders['X-Requested-With']) {
                this.initHeader('X-Requested-With', this.defaultXhrHeader, true);
            }
        }

        if(postData && this.useDefaultHeader && !this.headers['Content-Type']){
            this.initHeader('Content-Type', this.defaultPostHeader);
        }

        if (this.hasDefaultHeaders || this.hasHeaders) {
            this.setHeader(o);
        }

        this.handleReadyState(o, callback);
        o.conn.send(postData || null);

        return o;
    }
};